using System;
using System.Collections.Generic;
using System.Text;



namespace SQLToolbox.Lib
{
#pragma warning disable 1591
	
	/// <summary>
	/// 2 element tuple
	/// </summary>
	public class Tuple<A, B>
	{
		public readonly A a;
		public readonly B b;
		public Tuple(A a, B b) { this.a = a; this.b = b; }
		public Tuple(Tuple<A, B> tuple) { this.a = tuple.a; this.b = tuple.b; }

	}

	/// <summary>
	/// 3 element tuple
	/// </summary>
	public class Tuple<A, B, C>
	{
		public readonly A a;
		public readonly B b;
		public readonly C c;
		public Tuple(A a, B b, C c) { this.a = a; this.b = b; this.c = c; }
		public Tuple(Tuple<A, B, C> tuple) { this.a = tuple.a; this.b = tuple.b; this.c = tuple.c; }
	}

	/// <summary>
	/// 4 element tuple
	/// </summary>
	public class Tuple<A, B, C, D>
	{
		public readonly A a;
		public readonly B b;
		public readonly C c;
		public readonly D d;
		public Tuple(A a, B b, C c, D d) { this.a = a; this.b = b; this.c = c; this.d = d; }
		public Tuple(Tuple<A, B, C, D> tuple) { this.a = tuple.a; this.b = tuple.b; this.c = tuple.c; this.d = tuple.d; }
	}

	/// <summary>
	/// 5 element tuple
	/// </summary>
	public class Tuple<A, B, C, D, E>
	{
		public readonly A a;
		public readonly B b;
		public readonly C c;
		public readonly D d;
		public readonly E e;
		public Tuple(A a, B b, C c, D d, E e) { this.a = a; this.b = b; this.c = c; this.d = d; this.e = e; }
		public Tuple(Tuple<A, B, C, D, E> tuple) { this.a = tuple.a; this.b = tuple.b; this.c = tuple.c; this.d = tuple.d; this.e = tuple.e; }
	}

#pragma warning restore 1591

	/// <summary>
	/// Tuple factory and helper
	/// provides methods converting different types of delegates
	/// multiparamter action/function to single tuple parameter
	/// output parameter to return type
	/// action to function and vice versa
	/// </summary>
	[System.Diagnostics.DebuggerStepThroughAttribute]
	public static class Tuple
	{
		#region Tuple Factory
		/// <summary>
		/// Contruct tuple from 2 items
		/// </summary>
		public static Tuple<A, B> Create<A, B>(A a, B b)
		{
			return new Tuple<A, B>(a, b);
		}

		/// <summary>
		/// Contruct tuple from 3 items
		/// </summary>
		public static Tuple<A, B, C> Create<A, B, C>(A a, B b, C c)
		{
			return new Tuple<A, B, C>(a, b, c);
		}

		/// <summary>
		/// Contruct tuple from 4 items
		/// </summary>
		public static Tuple<A, B, C, D> Create<A, B, C, D>(A a, B b, C c, D d)
		{
			return new Tuple<A, B, C, D>(a, b, c, d);
		}

		/// <summary>
		/// Contruct tuple from 5 items
		/// </summary>
		public static Tuple<A, B, C, D, E> Create<A, B, C, D, E>(A a, B b, C c, D d, E e)
		{
			return new Tuple<A, B, C, D, E>(a, b, c, d, e);
		}
		#endregion
	}
}
